package com.haha.qqchannelbot.start;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.haha.qqchannelbot.config.GlobalConfig;
import com.haha.qqchannelbot.entity.Bot;
import jakarta.annotation.Resource;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.annotation.Order;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@SpringBootApplication
@Log4j2
@Order(0)
public class AccessToken implements CommandLineRunner {

    @Resource
    private RestTemplate restTemplate;

    @Value("${bot.app_id}")
    private String appId;


    @Value("${bot.app_secret:}")
    private String appSecret;

    @Value("${bot.access_url:}")
    private String accessUrl;

    /**
     * 是否使用新的鉴权方式
     */
    @Value("${bot.new_token:false}")
    private Boolean newToken;

    @Resource
    private Bot bot;


    @Override
    public void run(String... args) {
        log.info("初始化accessToken");
        if (!newToken) {
            log.info("不使用新的鉴权方式");
            return;
        }
        Map<String, String> params = new HashMap<>();
        params.put("appId", appId);
        params.put("clientSecret", appSecret);

        Thread accessTokenThread = new Thread(() -> {
            while (true) {
                try {
                    HttpClient httpClient = HttpClient.newHttpClient();
                    ObjectMapper objectMapper = new ObjectMapper();
                    HttpRequest request = HttpRequest.newBuilder()
                            .uri(URI.create(accessUrl))
                            .header("Content-Type", "application/json") // 设置请求头
                            .POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(params)))
                            .build();
                    HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
                    Map<String, Object> body = objectMapper.readValue(response.body(), Map.class);
                    log.info("accessToken body:{}", body);
                    String accessToken = body.get("access_token").toString();
                    Integer expiresIn = Integer.valueOf(body.get("expires_in").toString());
                    GlobalConfig.ACCESS_TOKEN = accessToken;
                    bot.setToken("QQBot " + accessToken);
                    TimeUnit.SECONDS.sleep(expiresIn - 10);
                } catch (IOException e){
                    log.error("消息发送或格式转换异常：", e);
                    try {
                        TimeUnit.SECONDS.sleep(10);
                    } catch (InterruptedException ex) {

                    }
                } catch (InterruptedException e) {
                    log.error("消息发送或休眠异常：", e);
                    try {
                        TimeUnit.SECONDS.sleep(10);
                    } catch (InterruptedException ex) {

                    }
                } catch (Exception e) {
                    log.error("获取accessToken异常：", e);
                    throw new RuntimeException("获取accessToken异常");
                }
            }
        });
        accessTokenThread.setDaemon(true);
        accessTokenThread.setName("AccessTokenThread");
        accessTokenThread.start();

        try {
            log.info("等待获取新鉴权码");
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {

        }

        if (GlobalConfig.ACCESS_TOKEN == null) {
            throw new RuntimeException("新鉴权码获取失败，可以考虑使用旧鉴权码，或稍后重试");
        }

    }


}
